<template>
  <div class="card h-full flex flex-col">
    <div class="status-box px-5 mb-4">
      <el-tabs v-model="tabName">
        <el-tab-pane v-for="sta of status" :key="sta.value" :name="sta.value">
          <template #label>
            <el-badge :value="sta.badgeValue" :offset="[10, 5]" :color="sta.color">{{
              sta.label
            }}</el-badge>
          </template>
        </el-tab-pane>
      </el-tabs>
    </div>
    <div class="search-box px-5 mb-4">
      <el-select
        class="group mr-4"
        v-model="selectValues"
        multiple
        collapse-tags
        :placeholder="selectPlaceholder"
      >
        <el-option
          v-for="so of selectOptions"
          :key="so.value"
          :value="so.value"
          :label="so.label"
        ></el-option>
      </el-select>
      <el-input class="keyword mr-4" v-model="keywordValue" :prefix-icon="Icons['Search']" />
      <el-dropdown trigger="click">
        <el-button class="self-center" text :icon="Icons['MoreFilled']"></el-button>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item>
              <el-button text :icon="Icons['Plus']" @click="emit('on-add')" v-if="permissionAdd">
                新增
              </el-button>
            </el-dropdown-item>
            <el-dropdown-item>
              <el-button text :icon="Icons['Printer']"> Print </el-button>
            </el-dropdown-item>
            <el-dropdown-item>
              <el-button text :icon="Icons['Download']"> Import </el-button>
            </el-dropdown-item>
            <el-dropdown-item>
              <el-button text :icon="Icons['Upload']"> Export </el-button>
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </div>
    <div class="where-box px-5 mb-4" v-show="whereBoxVisible">
      <el-row class="mb-2">
        <el-text>
          已找到 <el-text tag="b">{{ total }}</el-text> 条结果
        </el-text>
      </el-row>
      <el-row>
        <div class="where-item p-2 mr-2" v-for="wo of whereOptions" :key="wo.label">
          <el-text tag="b">{{ wo.label }} : </el-text>
          <el-tag
            class="ml-1"
            closable
            type="info"
            v-for="v of wo.values"
            :key="v.value"
            @close="onTagClose(v)"
          >
            {{ v.label }}
          </el-tag>
        </div>
        <el-button
          class="self-center"
          type="danger"
          text
          :icon="Icons['Delete']"
          @click="onTagCloseAll"
          >清空条件</el-button
        >
      </el-row>
    </div>

    <el-skeleton class="flex flex-1 mb-4 flex-col" :loading="loading" animated>
      <template #template>
        <el-skeleton-item variant="text" style="height: 40px" />
        <el-skeleton-item variant="text" class="flex-1 mt-2" />
        <el-skeleton-item variant="text" class="flex-1 mt-2" />
        <el-skeleton-item variant="text" class="flex-1 mt-2" />
        <el-skeleton-item variant="text" class="flex-1 mt-2" />
        <el-skeleton-item variant="text" class="flex-1 mt-2" />
        <el-skeleton-item variant="text" class="flex-1 mt-2" />
      </template>
      <el-table class="flex-1 mb-4" :data="tableData">
        <slot name="table-column"></slot>

        <el-table-column
          fixed="right"
          label=""
          width="100"
          v-if="permissionDelete || permissionEdit"
        >
          <template #default="{ row }">
            <el-button
              text
              :icon="Icons['Edit']"
              @click="emit('on-edit', row)"
              v-if="permissionEdit"
            ></el-button>

            <el-dropdown trigger="click">
              <el-button text :icon="Icons['More']"></el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item>
                    <el-button
                      type="danger"
                      text
                      :icon="Icons['Delete']"
                      @click="onDelete(row)"
                      v-if="permissionDelete"
                    >
                      Delete
                    </el-button>
                  </el-dropdown-item>
                  <el-dropdown-item>
                    <el-button
                      text
                      :icon="Icons['Edit']"
                      @click="emit('on-edit', row)"
                      v-if="permissionEdit"
                    >
                      Edit
                    </el-button>
                  </el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </template>
        </el-table-column>
      </el-table>
    </el-skeleton>

    <!-- 
      问题：修改 size 会导致 page 页数的数据为空，导致 el-pagination 内部进行一次 page 修正，但是这时候已经触发了 model size 更新了，会触发父级的 watchEffect，请求数据，发现数据为空，然后再修正 page 一次，又会触发一次父级的 watchEffect，又会触发请求一次，导致重复无用的加载。

      解决方案：监听 @size-change="page = 1" ，model size 更正后，让 model page 变成 1 ，这时候是同步修改的，effect 会再同一次更新触发。
     -->
    <el-pagination
      class="justify-between px-5 mb-4"
      v-model:current-page="page"
      v-model:page-size="size"
      :total="total"
      :small="true"
      :page-sizes="pageSizes"
      layout="total, sizes, prev, pager, next, jumper"
      @size-change="page = 1"
    />
  </div>
</template>

<script setup lang="ts" generic="TD = any">
import * as Icons from '@/icons'

export interface StatusItem {
  value: string
  label: string
  color: string
  badgeValue: number
}
export interface SelectOption {
  label: string
  value: string
}
export type WhereOptionValueType = 'keyword' | 'status' | 'selectOptions'
export interface WhereOptionValue {
  label: string
  value: string
  type: WhereOptionValueType
}
export interface WhereOption {
  label: string
  values: WhereOptionValue[]
}

const props = withDefaults(
  defineProps<{
    status: StatusItem[]
    total: number
    selectOptions: SelectOption[]
    loading: boolean
    tableData: TD[]
    pageSizes?: number[]
    selectPlaceholder?: string
    permissionAdd: boolean
    permissionEdit: boolean
    permissionDelete: boolean
  }>(),
  {
    selectPlaceholder: '请选择',
    pageSizes: () => [10, 20, 50, 100, 200],
    permissionAdd: false,
    permissionEdit: false,
    permissionDelete: false
  }
)

const emit = defineEmits(['on-add', 'on-edit', 'on-delete'])

const tabName = defineModel('tab', { type: String, default: 'All' })
const page = defineModel('page', { type: Number, default: 1 })
const size = defineModel('size', { type: Number, default: 20 })
const selectValues = defineModel<string[]>('select', { default: () => [] })
const keywordValue = defineModel('keyword', { type: String, default: '' })

const whereBoxVisible = computed<boolean>(() => {
  return whereOptions.value.length > 0
})
const whereOptions = computed<WhereOption[]>(() => {
  const r: WhereOption[] = []
  const s1 = props.selectOptions
    .filter((so) => selectValues.value.includes(so.value))
    .map((so) => ({
      label: so.label,
      value: so.value,
      type: 'selectOptions'
    }))
  if (s1.length > 0) {
    r.push({
      label: props.selectPlaceholder,
      values: s1 as WhereOptionValue[]
    })
  }

  if (tabName.value !== 'All') {
    const s2 = props.status
      .filter((s) => s.value === tabName.value)
      .map((s) => ({
        label: s.label,
        value: s.value,
        type: 'status'
      }))
    if (s2.length > 0) {
      r.push({
        label: '状态',
        values: s2 as WhereOptionValue[]
      })
    }
  }

  if (keywordValue.value) {
    r.push({
      label: '关键字',
      values: [{ label: keywordValue.value, value: keywordValue.value, type: 'keyword' }]
    })
  }
  return r
})

const onTagClose = (v: WhereOptionValue) => {
  if (v.type === 'keyword') {
    keywordValue.value = ''
  } else if (v.type === 'status') {
    tabName.value = 'All'
  } else if (v.type === 'selectOptions') {
    selectValues.value = selectValues.value.filter((sv) => sv !== v.value)
  }
}

const onTagCloseAll = () => {
  keywordValue.value = ''
  tabName.value = 'All'
  selectValues.value = []
}

const onDelete = (row: TD) => {
  emit('on-delete', row)
}
</script>

<style scoped lang="scss">
.status-box {
  position: relative;
  height: 40px;
  &::after {
    content: '';
    background-color: var(--el-border-color-light);
    bottom: 0;
    height: 2px;
    left: 0;
    position: absolute;
    width: 100%;
  }
}
.search-box {
  display: flex;
  .group {
    width: 200px;
  }
  :deep(.el-select__wrapper) {
    min-height: 2rem;
  }
  .keyword {
    flex: 1;
  }
}

.where-box {
  .where-item {
    display: inline-flex;
    border: 1px dashed rgba(145, 158, 171, 0.16);
    border-radius: 8px;
  }
}
.el-tabs {
  :deep(.el-tabs__header) {
    margin: 0;
  }
  :deep(.el-tabs__nav-wrap:after) {
    height: 0;
  }
}
.el-table {
  :deep(th.el-table__cell) {
    background-color: rgb(244, 246, 248);
  }
}
</style>
